﻿using System;
using Tesla.Bounding;
using Tesla.Core;
using Tesla.Graphics;
using Tesla.Input;
using Tesla.Math;
using Tesla.Scene;
using Tesla.Scene.Shape;

namespace TeslaSamples.Renderer {
    [AppDescription("Different Light Types", PlatformCapabilities.Direct3D10 | PlatformCapabilities.XNA4, "DifferentLightsImage", "DifferentLightsDesc", "DifferentLightsSource")]
    public class DifferentLights : BasicApp {
        private Light activeLight;
        private PointLight pl;
        private SpotLight sl;
        private DirectionalLight dl;
        private SpriteBatch batch;
        private SpriteFont font;
        private String text;

        protected override void LoadContent() {
            Window.Title = "Different Lights Sample";
            Type sp = typeof(Spatial);
            Type me = typeof(Mesh);

            bool ishash = sp.GetHashCode() == sp.GetHashCode();
            bool ishash2 = sp.GetHashCode() == me.GetHashCode();

            bool iseq = sp.Equals(sp);


            pl = new PointLight();
            pl.Specular = Color.DarkGray; //Cut down on the specular so we don't get blinded

            sl = new SpotLight();
            //Spot light angles - inner angle is where the light is most intense. The intensity smoothly
            //fades from this angle to the outer angle, so we don't have an abrupt cutoff. Essentially spot lights
            //are similar to point lights, except for this restricting cone.
            sl.OuterAngle = 45;
            sl.InnerAngle = 20;
            sl.Direction = new Vector3(-.577f, -.577f, -.577f);

            //Simple directional light - simulates a light source infinitely away like the Sun.
            dl = new DirectionalLight();
            dl.Direction = new Vector3(-.577f, -.577f, -.577f);

            activeLight = pl;

            //Create an inverted cube
            Box b = new Box("InsideOut", Vector3.Zero, 100, 100, 100, true);
            b.Material = ContentManager.Load<Material>("LitBasicColor.tem");
            b.RenderBucketType = RenderBucketType.Skip;

            //These are object material properties (built-in shaders also include Emissive, shininess factor, and an alpha factor)
            b.Material.SetParameter("MatDiffuse", Color.Crimson.ToVector3());
            b.Material.SetParameter("MatAmbient", new Color(.4f, .2f, .2f).ToVector3());
            b.Material.SetParameter("MatSpecular", new Color(.3f, .3f, .3f).ToVector3());
            b.SetModelBound(new BoundingBox());
            RootNode.AddChild(b);

            RootNode.RemoveAllLights();
            RootNode.AddLight(activeLight);
            text = "Active Light: Point";
            //Input response to set the active light
            InputLayer.RegisterTrigger(new InputTrigger(new KeyPressedCondition(Keys.D1, false), new InputAction(
                delegate(GameTime time) {
                    activeLight = pl;
                    RootNode.RemoveAllLights();
                    RootNode.AddLight(activeLight);
                    text = "Active Light: Point";
                }
            )));
            InputLayer.RegisterTrigger(new InputTrigger(new KeyPressedCondition(Keys.D2, false), new InputAction(
                delegate(GameTime time) {
                    activeLight = sl;
                    RootNode.RemoveAllLights();
                    RootNode.AddLight(activeLight);
                    text = "Active Light: Spot";
                }
            )));
            InputLayer.RegisterTrigger(new InputTrigger(new KeyPressedCondition(Keys.D3, false), new InputAction(
                delegate(GameTime time) {
                    activeLight = dl;
                    RootNode.RemoveAllLights();
                    RootNode.AddLight(activeLight);
                    text = "Active Light: Directional";
                }
            )));

            //Set up some text rendering
            batch = new SpriteBatch();
            font = ContentManager.Load<SpriteFont>("Fonts//comicsans.fnt");
        }

        protected override void OnRenderPost(IRenderer renderer) {
            batch.Begin();
            Viewport vp = renderer.CurrentCamera.Viewport;
            Vector2 pos = new Vector2(10, vp.Height - (font.MeasureString(text).Y + 10));
            batch.DrawString(font, text, pos, Color.White);
            batch.End();
        }
    }
}
